package durst.action.account;

import java.io.IOException;
import java.io.StringReader;
import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.FileBean;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.RedirectResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.StreamingResolution;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;
import net.sourceforge.stripes.validation.ValidationMethod;

import com.j256.ormlite.dao.Dao;

import durst.action.CalendarBasicAction;
import durst.data.Account;
import durst.data.Event;
import durst.data.Event.RepeatFrequency;
import durst.data.Invite;
import durst.data.UserCalendar;
import durst.data.dao.DaoFactory;
import durst.data.dao.impl.AccountDao;
import durst.exception.AccessDeniedException;
import durst.utils.BucketUtil;

public class EventCreateActionBean extends CalendarBasicAction {
	private boolean ajax;
	private FileBean file;

	@ValidateNestedProperties({ @Validate(field = "id", required = true, on = "!form", minvalue = 1) })
	private UserCalendar cal;

	@ValidateNestedProperties({
			@Validate(field = "title", required = true, maxlength = 15, on = "!form"),
			@Validate(field = "description", required = true, maxlength = 300, on = "!form"),
			@Validate(field = "repeated"), @Validate(field = "frequency"),
			@Validate(field = "startTime", required = true, on = "!form"),
			@Validate(field = "endTime", required = true, on = "!form"),
			@Validate(field = "doNotRepeatPast") })
	private Event event;

	@ValidateNestedProperties(@Validate(field = "id"))
	private List<Account> friends;

	@ValidationMethod(on = "!form")
	public void validateRepeated(ValidationErrors errors) throws SQLException {
		if (event.isRepeated()) {
			if (event.getFrequency() == RepeatFrequency.NONE)
				errors.add("frequency", new LocalizableError("validation.required.valueNotPresent"));
			else if (event.getDoNotRepeatPast() == null)
				errors.add("doNotRepeat", new LocalizableError(
						"validation.required.valueNotPresent"));
			else if (event.getDoNotRepeatPast().before(event.getStartTime())
					|| event.getDoNotRepeatPast().before(event.getEndTime()))
				errors.add("doNotRepeat", new LocalizableError("durst.action.event.badrepeat"));
		}
		else {
			event.setFrequency(RepeatFrequency.NONE);
			event.setDoNotRepeatPast(new Date());
		}

		if (event.getEndTime().before(event.getStartTime()))
			errors.add("startTime", new LocalizableError("durst.action.event.badtimes"));

		DaoFactory.getInstance().createDao(UserCalendar.class).refresh(cal);
		if (cal.getOwner().equals(context.getAccount()))
			event.setParent(cal);
		else
			throw new AccessDeniedException(true, context);
	}

	@DefaultHandler
	public Resolution form() {
		return new ForwardResolution("/account/eventform.jsp");
	}

	public Resolution create() throws SQLException, IOException {
		Dao<Event, Integer> eventDao = DaoFactory.getInstance().createDao(Event.class);

		eventDao.create(event);

		if (friends != null) {
			Dao<Invite, Integer> inviteDao = DaoFactory.getInstance().createDao(Invite.class);
			for (Account friend : friends)
				inviteDao.create(new Invite(friend, event, false));
		}

		if (file != null) {
			file.save(BucketUtil.createFile(context.getAccount(), event, file.getFileName()));
		}

		return ajax ? new StreamingResolution("text/javascript", new StringReader(
				"Lightview.hide(); invoke($('hidden_form'), 'same');")) : new RedirectResolution(
				ManageAccountActionBean.class);
	}

	public void setCal(UserCalendar cal) {
		this.cal = cal;
	}

	public UserCalendar getCal() {
		return cal;
	}

	public void setEvent(Event event) {
		this.event = event;
	}

	public Event getEvent() {
		return event;
	}

	public void setFriends(List<Account> friends) {
		this.friends = friends;
	}

	public List<Account> getFriends() {
		return friends;
	}

	public void setAjax(boolean ajax) {
		this.ajax = ajax;
	}

	public boolean isAjax() {
		return ajax;
	}

	public void setFile(FileBean file) {
		this.file = file;
	}

	public FileBean getFile() {
		return file;
	}
}
